/**
 * Created by Jiarui on 2015/12/7.
 */
//PCB结构
function PCB(name,status,pri,total,time,sorts) {
    this.name = name;//进程标识符
    this.status = status;//状态
    this.pri = pri;//优先级
    this.total = total;//总时间
    this.time = time;//剩余时间
    this.bar=0;//进度
    this.sorts = sorts;//用于标记前端位置
}

var PCBS = new Array(50); //进程控制块区域,系统允许进程个数为50
var totalNumber = 0;
var maxNumber = 50;
var maxIndex = 0;

function checkName(arr,temp,len){
    for(var i = 0; i < len; i++){
        if(arr[i] == temp)
            return true;
    }
    return false;
}

var $Queue = new Array(); //用于优先级调度创建优先级队列
var $QueueTime = new queue(); //时间轮转调度就绪队列
var $QueueForShort = new queue();   //最短进程优先就绪队列
var $QueueForShortLast = new queue();   //最短剩余时间就绪队列
var pri = 5;
var type = -1;
$Queue[0] = new queue();
$Queue[1] = new queue();
$Queue[2] = new queue();
$Queue[3] = new queue();
$Queue[4] = new queue();
$Queue[5] = new queue();
var nameArr = new Array();

function checkFree(){
    for(var i = 0; i < maxIndex; i++){
        if(PCBS[i].time == 0){
            return i;
        }
    }
    return 51;

}


/**
 * 创建进程
 */
function createProcess(){
    var nums = parseInt($('#numberOfProcess').val());
    if(isNaN(nums)){
        alert('输入数量格式不正确！');
        return;
    }
    if(nums <= 0 || nums > 50){
        alert('输入数量超过限制！');
        return;
    }
    if(type == -1){
        type = $('input[name="pro"]:checked ').val();
    }
    if((maxNumber - nums) < 0){
        return;
    }
    if(totalNumber == 0)
        $('.radio-header').attr('disabled','true');
    maxNumber = maxNumber - nums;
    $('#lastNumber').html(maxNumber);
    end = 0;
    var i = 0;
    while(i < nums){
        var temp = parseInt(Math.random()*1000 + 1);
        var tempN = totalNumber+i;
        if(checkName(nameArr,temp,tempN)){
            continue;
        }
        nameArr[tempN] = temp;
        i++;
    }
    var $tds = $('#template-list td');
    var $template_list_tbody = $('#template-list tbody');
    var template_render = $('#process-table tbody').html();
    var maxPri = 0;
    //var tempIndex = maxIndex;
    for(var j = 0; j < nums; j++){
        var pri1 = parseInt(Math.random()*5 + 1);
        if(pri1 >maxPri)
            maxPri = pri1;
        var time = parseInt(Math.random()*7 + 1);
        var index = totalNumber + j;
        var thePcb = new PCB(nameArr[index],1,pri1,time,time,index);
        var isExit = checkFree();
        if(isExit == 51){
            PCBS[maxIndex++] = thePcb;
        }else{
            PCBS[isExit] = thePcb;
        }
        if(type == 0){
            $QueueTime.addQueue(thePcb);
        }
        if(type == 1){
            if(thePcb.pri == 0){
                $Queue[0].addQueue(thePcb);
            }else if(thePcb.pri == 1){
                $Queue[1].addQueue(thePcb);
            }else if(thePcb.pri == 2){
                $Queue[2].addQueue(thePcb);
            }else if(thePcb.pri == 3){
                $Queue[3].addQueue(thePcb);
            }else if(thePcb.pri == 4){
                $Queue[4].addQueue(thePcb);
            }else if(thePcb.pri == 5){
                $Queue[5].addQueue(thePcb);
            }
        }
        if(type == 2){
            $QueueForShort.addQueue(thePcb);
        }
        if(type == 3){
            $QueueForShortLast.addQueue(thePcb);
        }
        $tds[0].innerHTML = thePcb.name;
        $tds[1].innerHTML = "就绪";
        $tds[2].innerHTML = thePcb.pri;
        $tds[3].innerHTML = thePcb.total;
        $tds[4].innerHTML = thePcb.time;
        $('#template-list tr').attr('id',index);
        $('#template-list .progress').attr('id','progress'+index);
        $('#template-list .progress__bar').attr('id','progress__bar'+index);
        $('#template-list .progress__text').attr('id','progress__text'+index);
        template_render += $template_list_tbody.html();
    }

    totalNumber+=nums;

    pri = maxPri;

    if(type == 2){
        for(var ii = 0; ii < $QueueForShort.size; ii++)
            for(var j = 0; j < $QueueForShort.size-ii-1; j++){
                if($QueueForShort.que[j].total > $QueueForShort.que[j+1].total){
                    var tempP = $QueueForShort.que[j];
                    $QueueForShort.que[j] = $QueueForShort.que[j+1];
                    $QueueForShort.que[j+1] = tempP;
                }
            }
    }

    if(type == 3){
        for(var ii = 0; ii < $QueueForShortLast.size; ii++)
            for(var j = 0; j < $QueueForShortLast.size-ii-1; j++){
                if($QueueForShortLast.que[j].time > $QueueForShortLast.que[j+1].time){
                    var tempP = $QueueForShortLast.que[j];
                    $QueueForShortLast.que[j] = $QueueForShortLast.que[j+1];
                    $QueueForShortLast.que[j+1] = tempP;
                }
            }
    }

    $('#process-table tbody').html(template_render);
}

/**
 * 重置进程
 */
function destroyProcess(){
    $('.radio-header').removeAttr('disabled','');
    PCBS = new Array();
    maxIndex = 0;
    type = -1;
    $Queue[0] = new queue();
    $Queue[1] = new queue();
    $Queue[2] = new queue();
    $Queue[3] = new queue();
    $Queue[4] = new queue();
    $Queue[5] = new queue();
    $QueueTime = new queue();
    $QueueForShort = new queue();
    $QueueForShortLast = new queue();
    end = 0;
    maxNumber = 50;
    clearInterval(timer1);
    $('#numberOfProcess').val('');
    $('#runTime').html('运行时间');
    PCBS = new Array();
    totalNumber = 0;
    timer1 = 0;
    $('#process-table tbody').html('');
    $('#lastNumber').html(50);
}

var orange = 30, yellow = 55, green = 85,time = 0;
var number = 0;
var end = 0;
var stopCount = 1;
var timer1 = 0;

/**
 * 开始模拟进程调度
 */
function runPro(){
    if(end == 1){
        alert('本次模拟已经结束，请重新创建进程！');
        return;
    }
    if(totalNumber == 0){
        alert('请先创建进程！');
        return;
    }
    if(timer1 != 0){
        return;
    }
    time = 0;
    number = 0;
    end = 0;
    stopCount = 1;
    var type = $('input[name="pro"]:checked ').val();
    if(type == 0)
        timer1 = setInterval("timeRollRun()",800);
    else if(type == 1) {
        timer1 = setInterval("priority()", 800);
    }
    else if(type == 2){
        timer1 = setInterval("short()", 800);
    }
    else if(type == 3) {
        timer1 = setInterval("shortLast()", 800);
    }
}


/**
 * 模拟时间片轮转
 */
function timeRollRun(){

    if (end == 0) {

        $('#runTime').html(++time);
        if ($QueueTime.size != 0) {
            var pTemp = $QueueTime.que[0];
            var i = 0;
            while(i < $QueueTime.size){
                var t = $QueueTime.que[i];
                var td = $('#'+ t.sorts+' td');
                td[1].innerHTML = "就绪";
                i++;
            }
            pTemp.time--;
            var tds = $('#'+pTemp.sorts+' td');
            tds[0].innerHTML = pTemp.name;
            tds[1].innerHTML = "运行";
            tds[2].innerHTML = pTemp.pri;
            tds[3].innerHTML = pTemp.total;
            tds[4].innerHTML = pTemp.time;

            var $progress = $('#progress'+pTemp.sorts), $bar = $('#progress__bar'+pTemp.sorts), $text = $('#progress__text'+pTemp.sorts);
            var percent = pTemp.bar = (parseFloat(pTemp.total) - parseFloat(pTemp.time)) / parseFloat(pTemp.total) * 100;
            percent = parseFloat(percent.toFixed(1));
            console.log(pTemp.sorts + ' ' + percent);
            $text.find('em').text(percent + '%');
            if (percent >= 100) {
                percent = 100;
                $progress.addClass('progress--complete');
                $bar.addClass('progress__bar--blue');
                $text.find('em').text('Complete');
            } else {
                if (percent >= green) {
                    $bar.addClass('progress__bar--green');
                } else if (percent >= yellow) {
                    $bar.addClass('progress__bar--yellow');
                } else if (percent >= orange) {
                    $bar.addClass('progress__bar--orange');
                }
            }
            $bar.css({ width: percent + '%' });


            if (pTemp.time == 0){
                tds[1].innerHTML = "终止";
                $QueueTime.popQueue();
                maxNumber++;
                $('#lastNumber').html(maxNumber);
            }else{
                var item = $QueueTime.popQueue();
                $QueueTime.addQueue(item);
            }

            if($QueueTime.size == 0){
                end = 1;
            }
        }

    }else{
        clearInterval(timer1);
        $('.radio-header').removeAttr('disabled','');
        alert('运行结束');
    }
}

function queue(){
    this.size = 0;
    this.que = new Array();
}

queue.prototype.addQueue = function (P) {
    this.que[this.size] = P;
    this.size++;
}

queue.prototype.popQueue = function(){
    var rp = this.que[0];
    for(var i = 0; i < this.size; i++){
        this.que[i] = this.que[i+1];
    }
    this.size--;
    return rp;
}

/**
 * 模拟优先级调度
 */
function priority(){

    if (end == 0) {

        $('#runTime').html(++time);
        if ($Queue[pri].size != 0) {
            var pTemp = $Queue[pri].popQueue();
            for(var j = 0; j <= pri; j++){
                var i = 0;
                while(i < $Queue[j].size){
                    var t = $Queue[j].que[i];
                    var td = $('#'+ t.sorts+' td');
                    td[1].innerHTML = "就绪";
                    i++;
                }
            }
            pTemp.time--;
            if(pTemp.pri>0)
                pTemp.pri--;
            var tds = $('#'+pTemp.sorts+' td');
            tds[0].innerHTML = pTemp.name;
            tds[1].innerHTML = "运行";
            tds[2].innerHTML = pTemp.pri;
            tds[3].innerHTML = pTemp.total;
            tds[4].innerHTML = pTemp.time;

            var $progress = $('#progress'+pTemp.sorts), $bar = $('#progress__bar'+pTemp.sorts), $text = $('#progress__text'+pTemp.sorts);
            var percent = pTemp.bar = (parseFloat(pTemp.total) - parseFloat(pTemp.time)) / parseFloat(pTemp.total) * 100;
            percent = parseFloat(percent.toFixed(1));
            console.log(pTemp.sorts + ' ' + percent);
            $text.find('em').text(percent + '%');
            if (percent >= 100) {
                percent = 100;
                $progress.addClass('progress--complete');
                $bar.addClass('progress__bar--blue');
                $text.find('em').text('Complete');
            } else {
                if (percent >= green) {
                    $bar.addClass('progress__bar--green');
                } else if (percent >= yellow) {
                    $bar.addClass('progress__bar--yellow');
                } else if (percent >= orange) {
                    $bar.addClass('progress__bar--orange');
                }
            }
            $bar.css({ width: percent + '%' });


            if (pTemp.time == 0){
                tds[1].innerHTML = "终止";
                maxNumber++;
                $('#lastNumber').html(maxNumber);
            }else if(pTemp.pri == 0)
                $Queue[0].addQueue(pTemp);
            else
                $Queue[pri-1].addQueue(pTemp);

            if($Queue[pri].size == 0){
                pri--;
            }

            if(pri < 0){
                end = 1;
            }
        }else{
            pri--;
        }

    }else{
        clearInterval(timer1);
        $('.radio-header').removeAttr('disabled','');
        alert('运行结束');
    }

}

/**
 * 模拟最短进程优先
 */
function short(){

    if (end == 0) {

        $('#runTime').html(++time);
        if ($QueueForShort.size != 0) {
            var pTemp = $QueueForShort.que[0];
            pTemp.time--;
            var tds = $('#'+pTemp.sorts+' td');
            tds[0].innerHTML = pTemp.name;
            tds[1].innerHTML = "运行";
            tds[2].innerHTML = pTemp.pri;
            tds[3].innerHTML = pTemp.total;
            tds[4].innerHTML = pTemp.time;

            var $progress = $('#progress'+pTemp.sorts), $bar = $('#progress__bar'+pTemp.sorts), $text = $('#progress__text'+pTemp.sorts);
            var percent = pTemp.bar = (parseFloat(pTemp.total) - parseFloat(pTemp.time)) / parseFloat(pTemp.total) * 100;
            percent = parseFloat(percent.toFixed(1));
            console.log(pTemp.sorts + ' ' + percent);
            $text.find('em').text(percent + '%');
            if (percent >= 100) {
                percent = 100;
                $progress.addClass('progress--complete');
                $bar.addClass('progress__bar--blue');
                $text.find('em').text('Complete');
            } else {
                if (percent >= green) {
                    $bar.addClass('progress__bar--green');
                } else if (percent >= yellow) {
                    $bar.addClass('progress__bar--yellow');
                } else if (percent >= orange) {
                    $bar.addClass('progress__bar--orange');
                }
            }
            $bar.css({ width: percent + '%' });


            if (pTemp.time == 0){
                tds[1].innerHTML = "终止";
                $QueueForShort.popQueue();
                maxNumber++;
                $('#lastNumber').html(maxNumber);
            }

            if($QueueForShort.size == 0){
                end = 1;
            }
        }

    }else{
        clearInterval(timer1);
        $('.radio-header').removeAttr('disabled','');
        alert('运行结束');
    }

}

function shortLast(){

    if (end == 0) {

        $('#runTime').html(++time);
        if ($QueueForShortLast.size != 0) {
            var pTemp = $QueueForShortLast.que[0];
            pTemp.time--;
            var tds = $('#'+pTemp.sorts+' td');
            tds[0].innerHTML = pTemp.name;
            tds[1].innerHTML = "运行";
            tds[2].innerHTML = pTemp.pri;
            tds[3].innerHTML = pTemp.total;
            tds[4].innerHTML = pTemp.time;

            var $progress = $('#progress'+pTemp.sorts), $bar = $('#progress__bar'+pTemp.sorts), $text = $('#progress__text'+pTemp.sorts);
            var percent = pTemp.bar = (parseFloat(pTemp.total) - parseFloat(pTemp.time)) / parseFloat(pTemp.total) * 100;
            percent = parseFloat(percent.toFixed(1));
            console.log(pTemp.sorts + ' ' + percent);
            $text.find('em').text(percent + '%');
            if (percent >= 100) {
                percent = 100;
                $progress.addClass('progress--complete');
                $bar.addClass('progress__bar--blue');
                $text.find('em').text('Complete');
            } else {
                if (percent >= green) {
                    $bar.addClass('progress__bar--green');
                } else if (percent >= yellow) {
                    $bar.addClass('progress__bar--yellow');
                } else if (percent >= orange) {
                    $bar.addClass('progress__bar--orange');
                }
            }
            $bar.css({ width: percent + '%' });


            if (pTemp.time == 0){
                tds[1].innerHTML = "终止";
                $QueueForShortLast.popQueue();
                maxNumber++;
                $('#lastNumber').html(maxNumber);
            }

            if($QueueForShortLast.size == 0){
                end = 1;
            }
        }

    }else{
        clearInterval(timer1);
        $('.radio-header').removeAttr('disabled','');
        alert('运行结束');
    }

}